package com.sduept.nwld.dataserver.controller.equipment.assessment;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

import org.primefaces.PrimeFaces;

import com.sduept.bigdata.equipment.assessment.enums.InspectionType;
import com.sduept.bigdata.equipment.assessment.exception.ParameterException;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionPlan;
import com.sduept.bigdata.equipment.assessment.model.inspection.InspectionStation;
import com.sduept.bigdata.equipment.assessment.service.InspectionPlanService;
import com.sduept.bigdata.equipment.assessment.service.InspectionStationService;
import com.sduept.bigdata.equipment.assessment.service.RectificationPlanService;
import com.sduept.bigdata.equipment.assessment.service.impl.DeductionTaskService;
import com.sduept.bigdata.web.jsf.controller.AbstractController;
import com.sduept.permission.cache.PermissionDataCache;
import com.sduept.permission.entity.PersonnelEntityBean;
import com.sduept.permission.entity.RoleEntityBean;
import com.sduept.utils.PingYinUtil;
/**
 * 评价计划管理页面控制器
 * @author pengz
 *
 */
@Named
@ViewScoped
public class AssessmentPlanListController extends AbstractController{

	private static final long serialVersionUID = -4356344402435206290L;
	
	@Autowired
	private InspectionPlanService planService;
	@Autowired
	private InspectionStationService instationService;
	@Autowired
	private DeductionTaskService deductService;
	@Autowired
	private RectificationPlanService service;
	/**
	 * 当前用户是否是管理员
	 */
	private boolean admin;
	/**
	 * dataTable展示的评价计划集合
	 */
	private List<InspectionPlan> plans = new ArrayList<InspectionPlan>();
	/**
	 * 缓存所有的评价计划，与数据库保持一致
	 */
	private List<InspectionPlan> planAll = new ArrayList<InspectionPlan>();	
	/**
	 * 所有的评价计划，map形式缓存
	 */
	private Map<String,InspectionPlan> planMap = new HashMap<String, InspectionPlan>();
	/**
	 * 选中的评价计划
	 */
	private List<InspectionPlan> selectedInspectionPlans = new ArrayList<InspectionPlan>();
	/**
	 * 页面显示的评价计划数量
	 */
	private int count;	
	/**
	 * 查询条件
	 */
	private CustomQuery query; 
	/**
	 * key:负责人首字母
	 * value:负责人名称集合
	 */
	private  Map<String, List<String>> personNameMap = new HashMap<String, List<String>>();
	/**
	 * 当前库中所有人员
	 */
	List<PersonnelEntityBean> personnels = new ArrayList<PersonnelEntityBean>();
	/**
	 * 计划状态颜色
	 */
	private String statusColor;
	
	private Map<String,InspectionPlan> finishedPlan = new HashMap<String, InspectionPlan>();
	{
		query = new CustomQuery();
	}
	@PostConstruct
	public void init() {
		getCurrentUserIdentity();
		initPlansData();
		personnels.clear();
		personnels.addAll(PermissionDataCache.getInstance().getPersonMap().values());
		initPersonNameMap();
	}
	/**
	 * 判断当前用户是否是管理员
	 */
	private void getCurrentUserIdentity() {
		PersonnelEntityBean user = getCurrentUser();
		// 判断是否为管理员
		Set<RoleEntityBean> roles = user.getRoles();
		for (RoleEntityBean role : roles) {
			if("system".equals(role.getType())) {
//			if("管理员".equals(role.getName())) {
				admin = true;
				break;
			}
		}
	}
	/**
	 * 初始化页面需要展示的评价计划
	 */
	private void initPlansData() {
		if(admin) {//如果是当前用户是管理员，则查询所有的评价计划
			plans = planService.findAll();
		}else {//只查询该用户创建的评价计划
			plans = planService.findInspectionPlanByCondition(getCurrentUser().getName(),null,null,null,null);
		}
		Iterator<InspectionPlan> it = plans.iterator();
		while(it.hasNext()) {
			InspectionPlan insPlan = it.next();
			if(insPlan.getStatus()==5) {
				it.remove();
			}
		}
		planAll.clear();
		planAll.addAll(plans);
		planMap.clear();
		for(InspectionPlan plan : plans) {
			planMap.put(plan.getId(), plan);
		}
		count = plans.size();
	}	
	/**
	 * 初始化personNameMap
	 */
	private void initPersonNameMap() {
		personNameMap.clear();
		for (PersonnelEntityBean personnelEntityBean : personnels) {
			String key  = PingYinUtil.getPingYinHeader(personnelEntityBean.getName());
			List<String> value =personNameMap.get(key);
			if(value==null) {
				value = new ArrayList<String>();
				personNameMap.put(key, value);
			}
			value.add(personnelEntityBean.getName());
		}
	}
	public List<String> completePersonnals(String query) {
		List<String> result = new ArrayList<String>();
		for (String s : personNameMap.keySet()) {
			if(s.startsWith(query)) {
				result.addAll(personNameMap.get(s));
			}
		}
		return result;
	}
	/**
	 * 删除所有选中的计划
	 */
	public void delete() {
		for(InspectionPlan inspectionPlan : selectedInspectionPlans) {
			inspectionPlan.setStatus(5);
			planService.createOrupdate(inspectionPlan);
			plans.remove(inspectionPlan);
			planAll.remove(inspectionPlan);
			planMap.remove(inspectionPlan.getId());
		}
		List<InspectionPlan> needDeleteInspectionPlans = new ArrayList<InspectionPlan>();
		needDeleteInspectionPlans.addAll(selectedInspectionPlans);
		//另开一个线程删除
		new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					for(InspectionPlan inspectionPlan : needDeleteInspectionPlans) { 
						planService.deleteById(inspectionPlan.getId());
						// 删除该计划对应的整改计划
						service.deleteByInspectionPlanId(inspectionPlan.getId());
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		}).start();
		//更新展示的评价计划数量
		count = plans.size();
		selectedInspectionPlans = new ArrayList<InspectionPlan>();
		addSuccessMessage("删除成功");
	}
	/**
	 * 新建计划弹窗返回处理函数
	 */
	public void onAddInspectPlanDialogReturn() {
		String inspectPlanId = getParameter("inspectionPlanId");
		InspectionPlan inspectionPlan = planService.findById(inspectPlanId);
		plans.add(inspectionPlan);
		planAll.add(inspectionPlan);
		planMap.put(inspectPlanId, inspectionPlan);
		addSuccessMessage("创建成功！");
	}
	/**
	 * 打开编辑评价计划dialog页面
	 */
	public void openEditInspectionPlanDialog() {
		String targetSrc = "";
		String title = "";
		String type = "";
		InspectionPlan selectedPlan = selectedInspectionPlans.get(0);
		if(selectedPlan.getInspectionType().equals(InspectionType.INSPECTIONOTHER)) {
			targetSrc = "/ui/equipmentAssessment/assessmentplan/dialog/addInspectOtherPlanDialog.xhtml?id="+selectedPlan.getId();
			title = "互查计划-编辑";
			type = "InspectOther";
		}else {
			targetSrc = "/ui/equipmentAssessment/assessmentplan/dialog/addOrEditInspectSelfPlanDialog.xhtml?id="+selectedPlan.getId();
			title = "自查计划-编辑";
			type = "InspectSelf";
		}
		PrimeFaces.current().executeScript("openEditInspectionPlanDialog('"+targetSrc+"','"+title+"','"+type+"')");
	}
	/**
	 * 编辑计划（自查、互查）弹窗返回处理函数
	 */
	public void onEditInspectPlanDialogReturn() {
		String inspectPlanId = getParameter("inspectionPlanId");
		InspectionPlan inspectionPlan = planService.findById(inspectPlanId);
		InspectionPlan oldPlan = planMap.get(inspectPlanId);
		int index1 = plans.indexOf(oldPlan);
		plans.remove(index1);
		plans.add(index1, inspectionPlan);
		int index2 = planAll.indexOf(oldPlan);
		planAll.remove(index2);
		planAll.add(index2, inspectionPlan);
		planMap.replace(inspectPlanId, inspectionPlan);
		addSuccessMessage("编辑成功！");
	}
	/**
	 * 发布计划
	 * @param id
	 */
	public void publish(String id) {
		InspectionPlan insPlan = planMap.get(id);
		if(insPlan.getStartTime()==null||insPlan.getEndTime()==null) {
			alertErrorMessage("发布失败！原因：该计划未选择评价时间");
			return;
		}
		if(insPlan.getResponsible()==null) {
			alertErrorMessage("发布失败！原因：该计划未选择责任人");
			return;
		}
		insPlan.setStatus(1);
		planService.createOrupdate(insPlan);
		addSuccessMessage("发布成功！");
	}
	/**
	 * 立即执行计划
	 * @param id
	 */
	public void executeNow(String id) {
		InspectionPlan insPlan = planMap.get(id);
		if(insPlan.getStartTime()==null||insPlan.getEndTime()==null) {
			alertErrorMessage("发布失败！原因：该计划未选择评价时间");
			return;
		}
		if(insPlan.getResponsible()==null) {
			alertErrorMessage("发布失败！原因：该计划未选择责任人");
			return;
		}
		insPlan.setStatus(2);
		insPlan.setActualStartTime(new Date());
		try {
			Set<InspectionStation> instations = instationService.findByInspectionPlan(id);
			for (InspectionStation inspectionStation : instations) {
				inspectionStation.setStatus(1);//评价站状态设置为进行中
			}
			insPlan.setInspectSubStations(instations);
		} catch (ParameterException e) {
			addErrorMessage("计划执行失败！");
		}
		planService.createOrupdate(insPlan);
		addSuccessMessage("执行成功！");
	}
	/**
	 * 将已发布的计划返回成草稿状态
	 * @param id
	 */
	public void returnToDraft(String id) {
		InspectionPlan insPlan = planMap.get(id);
		insPlan.setStatus(0);
		planService.createOrupdate(insPlan);
		addSuccessMessage("撤销发布成功！");
	}
	/**
	 * 提交计划
	 * @param id
	 */
	public void submit(String id) {
		//1、提交计划
		InspectionPlan insPlan = planMap.get(id);
		insPlan.setStatus(3);
		insPlan.setActualEndTime(new Date());
		planService.createOrupdate(insPlan);
		//2、清除扣分服务类中的缓存数据
		deductService.clearInspectionStationCacheByPlanId(id);
		addSuccessMessage("计划提交成功！");
	}
	/**
	 * 刷新刚新建并且数据还未保存完成的计划
	 * @param id
	 */
	public void refresh(String id) {
		InspectionPlan previousPlan = planMap.get(id);
		InspectionPlan currentPlan = planService.findById(id);
		if(currentPlan.getStatus()==0) {
			int index1 = plans.indexOf(previousPlan);
			plans.remove(index1);
			plans.add(index1, currentPlan);
			int index2 = planAll.indexOf(previousPlan);
			planAll.remove(index2);
			planAll.add(index2, currentPlan);
			planMap.replace(id, currentPlan);
			PrimeFaces.current().ajax().update(Arrays.asList("form:dataTb"));
		}else {
			FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"注意", "数据存储中，请稍后重试！");
	        FacesContext.getCurrentInstance().addMessage("提示", facesMsg);
	        PrimeFaces.current().ajax().update(Arrays.asList("form:msgs"));
		}
	}
	/**
	 * 获得计划提交时提示信息
	 * @param id 计划id
	 * @return
	 */
	public String getSubmitMessage(String id) {
		int num = 0;
		try {
			Set<InspectionStation> instations = instationService.findByInspectionPlan(id);
			instations = new HashSet<InspectionStation>();
			for (InspectionStation inspectionStation : instations) {
				if(inspectionStation.getStatus()!=2) {
					num++;
				}
			}
		} catch (ParameterException e) {
			e.printStackTrace();
		}
		if(num==0) {
			return "确定提交吗？";
		}else {
			return " 该计划还有 【 "+num+" 】个评价厂站未评价，确定提交吗？";            
		}
	}
	/**
	 * 条件查询
	 */
	public void query() {
		if(query.getStartTime()!=null) {
			if(query.getEndTime()==null) {
				FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"提示","请提供具体的结束时间！");
				PrimeFaces.current().dialog().showMessageDynamic(facesMsg);
				return;
			}
		}
		if(query.getEndTime()!=null) {
			if(query.getStartTime()==null) {
				FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_WARN,"提示","请提供具体的开始时间！");
				PrimeFaces.current().dialog().showMessageDynamic(facesMsg);
				return;
			}
		}
		selectedInspectionPlans.clear();
		if(query.getCreator()==null&&query.getResponsible()==null&&query.getStartTime()==null&&query.getEndTime()==null&&query.getStatus()==null) {
			plans = planAll;
		}else {
//			plans = service.findInspectionPlanByCondition(query.getCreator(), query.getResponsible(), query.getStartTime(), query.getEndTime(), query.getStatus());
			plans = filterPlans(query.getCreator(), query.getResponsible(), query.getStartTime(), query.getEndTime(), query.getStatus());
		}
		count = plans.size();
	}
	/**
	 * 对所有的计划进行过滤展示
	 * @param creator
	 * @param responsible
	 * @param start
	 * @param end
	 * @param status
	 * @return
	 */
	private List<InspectionPlan> filterPlans(String creator, String responsible, Date start, Date end, Integer status) {
		List<InspectionPlan> result = new ArrayList<InspectionPlan>();
		for(InspectionPlan plan : planAll) {
			boolean required = true;
			if(creator!=null) {
				if(!creator.equals(plan.getCreator())) {
					required = false;
					continue;
				}
			}
			if(responsible!=null) {
				if(!responsible.equals(plan.getResponsible())) {
					required = false;
					continue;
				}
			}
			if(start!=null) {
				if(start.after(plan.getStartTime())) {
					required = false;
					continue;
				}
			}
			if(end!=null) {
				if(end.before(plan.getEndTime())) {
					required = false;
					continue;
				}
			}
			if(status!=null) {
				if(plan.getStatus() != status.intValue()) {
					required = false;
					continue;
				}
			}
			if(required) {
				result.add(plan);
			}
		}
		return result;
	}
	/**
	 * 清空条件
	 */
	public void clearQuery() {
		query = new CustomQuery();
		plans = planAll;
		count = plans.size();
	}
	/**
	 * 根据参数获得所有符合条件的评价计划名称
	 * @param query：计划名称的一部分
	 * @return
	 */
	public List<String> completePlanName(String query) {
		List<String>names = new ArrayList<String>();
		names.add("全部");
		if (Pattern.matches("[a-z]{1,}", query)) {
			for (InspectionPlan plan : planAll) {
				String nameHead = PingYinUtil.getPingYinHeader(plan.getName());
				if (nameHead.toLowerCase().contains(query)) {
					names.add(plan.getName());
				}
			}
		}else{
			for (InspectionPlan plan : planAll) {
				if (plan.getName().contains(query)) {
					names.add(plan.getName());
				}
			}
		}
		return names;
	}
	/**
	 * 根据queryPlanName模糊查询
	 */
	public void queryByName() {
		List<InspectionPlan> selectedPlans = new ArrayList<InspectionPlan>();
		if("全部".equals(query.getPlanName())) {
			selectedPlans.addAll(planAll);
		}else {
			selectedInspectionPlans.clear();
			for(InspectionPlan plan : planAll) {
				if(query.getPlanName().equals(plan.getName())) {
					selectedPlans.add(plan);
				}
			}
		}
		plans = selectedPlans;
		count = plans.size();
	}
	/**
	 * 编辑按钮是否可用
	 * @return
	 */
	public boolean showEdit() {
		boolean disabled = true;
		if(selectedInspectionPlans!=null&&selectedInspectionPlans.size()==1&&selectedInspectionPlans.get(0).getStatus()==0) {
			return false;
		}
		return disabled;
	}
	/**
	 * 查看按钮是否可用
	 * @return
	 */
	public boolean disabledDetailBtn() {
		boolean disabled = true;
		if(selectedInspectionPlans!=null&&selectedInspectionPlans.size()==1&&selectedInspectionPlans.get(0).getStatus()!=4) {
			disabled = false;
		}
		return disabled;
	}
	/**
	 * 删除按钮是否可用
	 * @return
	 */
	public boolean disabledDelBtn() {
		boolean disabled = true;
		if(selectedInspectionPlans!=null&&!selectedInspectionPlans.isEmpty()) {
			for(InspectionPlan inPlan : selectedInspectionPlans) {
				if(inPlan.getStatus()!=4) {
					return false;
				}
			}
		}
		return disabled;
	}
	/**
	 * 获得选中的第一个计划
	 * @return
	 */
	public InspectionPlan getSelectedInspectionPlan() {
		if(selectedInspectionPlans!=null&&selectedInspectionPlans.size()==1) {
			return selectedInspectionPlans.get(0);
		}
		return new InspectionPlan();
	}
	/**
	 * 获取不同状态对应的展示内容
	 * @param id 计划id
	 * @param status 计划状态
	 * @return
	 */
	public String getStatusStr(String id,int status) {
		StringBuffer statusStr = new StringBuffer();
		switch (status) {
		case 0:
			statusStr.append("草稿");
			statusColor="#0998ea";
			break;
		case 1:
			statusStr.append("已发布");
			statusColor="blue";
			break;
		case 2:
			statusStr.append("进行中");
			statusColor="red";
			if(finishedPlan.containsKey(id)) {
				statusStr.append("【完成】");
			}
			break;
		case 3:
			statusStr.append("已 完成");
			statusColor="green";
			break;
		case 4:
			statusStr.append("草稿");
			statusColor="#0998ea";
			break;
		default:
			break;
		}
		return statusStr.toString();
	}
	/**
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public String getTimeStr(Date start,Date end) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		if(start==null&&end==null) {
			return "";
		}
		if(start!=null&&end==null) {
			return "（起）"+dateFormat.format(start);
		}
		if(start==null&&end!=null) {
			return "（止）"+dateFormat.format(end);
		}
		return dateFormat.format(start)+"至"+dateFormat.format(end);
	}
	/**
	 * 评价计划管理页面查询条件模型
	 * @author pengz
	 *
	 */
	public class CustomQuery {
		private String station;
		private Date startTime;
		private Date endTime;
		private Integer status;
		private String planName;
		private String responsible;
		private String creator;
		public String getStation() {
			return station;
		}
		public void setStation(String station) {
			this.station = station;
		}
		public Date getStartTime() {
			return startTime;
		}
		public void setStartTime(Date startTime) {
			this.startTime = startTime;
		}
		public Date getEndTime() {
			return endTime;
		}
		public void setEndTime(Date endTime) {
			this.endTime = endTime;
		}
		public Integer getStatus() {
			return status;
		}
		public void setStatus(Integer status) {
			this.status = status;
		}
		public String getPlanName() {
			return planName;
		}
		public void setPlanName(String planName) {
			this.planName = planName;
		}
		public String getResponsible() {
			return responsible;
		}
		public void setResponsible(String responsible) {
			this.responsible = responsible;
		}
		public String getCreator() {
			return creator;
		}
		public void setCreator(String creator) {
			this.creator = creator;
		}
		
	}
	public List<InspectionPlan> getPlans() {
		return plans;
	}

	public void setPlans(List<InspectionPlan> plans) {
		this.plans = plans;
	}
	
	public int getCount() {
		return count;
	}
	public void setCount(int count) {
		this.count = count;
	}
	public List<InspectionPlan> getPlanAll() {
		return planAll;
	}
	public void setPlanAll(List<InspectionPlan> planAll) {
		this.planAll = planAll;
	}
	public CustomQuery getQuery() {
		return query;
	}
	public void setQuery(CustomQuery query) {
		this.query = query;
	}
	public List<InspectionPlan> getSelectedInspectionPlans() {
		return selectedInspectionPlans;
	}
	public void setSelectedInspectionPlans(List<InspectionPlan> selectedInspectionPlans) {
		this.selectedInspectionPlans = selectedInspectionPlans;
	}
	public Map<String, List<String>> getPersonNameMap() {
		return personNameMap;
	}
	public void setPersonNameMap(Map<String, List<String>> personNameMap) {
		this.personNameMap = personNameMap;
	}
	public List<PersonnelEntityBean> getPersonnels() {
		return personnels;
	}
	public void setPersonnels(List<PersonnelEntityBean> personnels) {
		this.personnels = personnels;
	}
	public String getStatusColor() {
		return statusColor;
	}
	public void setStatusColor(String statusColor) {
		this.statusColor = statusColor;
	}
	public boolean isAdmin() {
		return admin;
	}
	public void setAdmin(boolean admin) {
		this.admin = admin;
	}
	
	
}
